import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:t3_data_service/data_provider/map_sctx/t3_map_sctx_provider.dart';
import 'package:t3_map/t3_map_plugin/map/core/t3_location.dart';
import 'package:t3_map/address_select.dart';

import 't3_map_platform_interface.dart';

/// An implementation of [T3MapPlatform] that uses method channels.
class MethodChannelT3Map extends T3MapPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('t3_map');

  @override
  Future<String?> getPlatformVersion() async {
    final version =
    await methodChannel.invokeMethod<String>('getPlatformVersion');

    return version;
  }

  /// 返回数据格式
  /// ```json
  ///   {
  ///     "routes": [{
  ///         "duration": 60,
  ///         "distance": 100,
  ///         "tolls": 0,
  ///         "trafficLightCount": 2,
  ///         "polyline" : ".....",
  ///     }]
  ///   }
  /// ```
  @override
  Future<String?> getWalkRoute({
    required T3MapType mapType,
    required T3LocationCoordinate2D origin,
    required T3LocationCoordinate2D destination}) async {
    final json = {
      "mapType": mapType.value,
      "origin": origin.toJson(),
      "destination": destination.toJson(),
    };

    final string = jsonEncode(json);
    final route = await methodChannel.invokeMethod<String>(
        'walkingRoute#calculate', string);
    return route;
  }

  /// 返回数据格式
  /// ```json
  ///   {
  ///     "routes": [{
  ///         "duration": 60,
  ///         "distance": 100,
  ///         "tolls": 0,
  ///         "trafficLightCount": 2,
  ///         "polyline" : ".....",
  ///         "tag": ""
  ///     }]
  ///   }
  /// ```
  @override
  Future<String?> getDriveRoute({
   required T3MapType mapType, 
    required T3LocationCoordinate2D origin, 
    required T3LocationCoordinate2D destination,
    List<T3LocationCoordinate2D>? viaPoints,
    String? originPoiId,
    String? destPoiId,
    double? departureTime}) async {
    
    var json = {
      "mapType": mapType.value,
      "origin": origin.toJson(),
      "destination": destination.toJson(),
    };

    if (viaPoints != null) {
      json['via'] = viaPoints.map((e) => e.toJson()).toList();
    }

    if (originPoiId != null) {
      json['originPoiId'] = originPoiId;
    }

    if (destPoiId != null) {
      json['destPoiId'] = destPoiId;
    }

    if (departureTime != null) {
      json['departureTime'] = departureTime;
    }

    final string = jsonEncode(json);
    final route = await methodChannel.invokeMethod<String>('driveRoute#calculate', string);
    return route;
  }

  @override
  Future<String?> getRegeo(
      {required T3MapType mapType, required T3LocationCoordinate2D coordinate}) async {
    final json = {
      "mapType": mapType.value,
      "longitude": coordinate.longitude,
      "latitude": coordinate.latitude,
    };

    final string = jsonEncode(json);
    final regeo = await methodChannel.invokeMethod<String>('poi#regeo', string);
    return regeo;
  }

  MethodChannelT3Map() {
    print("callSelectAddress--- init");
    methodChannel.setMethodCallHandler((call) async {
      print("callSelectAddress--- async");
      var methodName = call.method;
      var params = call.arguments;
      if (methodName.isEmpty) {
        return Future.value(null);
      }
      switch (call.method) {
        case 'selectAddress':
          dynamic result = await nativeCallFlutterSelectAddress(params);
          if (result!= null && result is Map) {
            List<Map<String, dynamic>> list = result["data"];
            if (list.isEmpty) {
              return Future.value(null);
            }
            return Future.value(list.first);
          }
        default:
          return Future.value(null);
      }
    });
  }
}
